#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
#include <ctime>

using namespace std;

bool win = false;
bool key = false;

class Matrix
{
private:
    int rows, cols;
    vector<vector<double>> data;

public:
    // 构造函数
    Matrix() {}
    Matrix(int r, int c) : rows(r), cols(c)
    {
        vector<double> tmp;
        for (int i = 0; i < cols; i++)
        {
            tmp.push_back(0);
        }
        data.push_back(tmp);
        for (int i = 1; i < rows - 1; i++)
        {
            vector<double> tmp;
            tmp.push_back(0);
            for (int j = 1; j < cols - 1; j++)
            {
                tmp.push_back(-1);
            }
            tmp.push_back(0);
            data.push_back(tmp);
        }
        data.push_back(tmp);
    }

    // 获取矩阵行数
    int getRows() const { return rows; }

    // 获取矩阵列数
    int getCols() const { return cols; }

    // 获取矩阵某个元素的值
    double get(int row, int col) const { return data[row][col]; }

    // 设置矩阵某个元素的值
    void set(int row, int col, double val) { data[row][col] = val; }

    double operator()(int _x, int _y)
    {
        return data[_x][_y];
    }

    // 打印矩阵
    void print(int _i, int _j) const
    {
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                if (i == _i && j == _j)
                    cout << "|*|"
                         << "\t";
                else
                {
                    // cout << data[i][j] << "\t" ;
                    if (data[i][j] == 0)
                        cout << " " << data[i][j]
                             << "\t";
                    else
                        cout << "| |"
                             << "\t";
                }
            }
            cout << endl;
        }
    }
};

class lobby
{
private:
public:
    string enter()
    {
        if (win == false)
        {
            cout << "You need to save the prisoned princess! Let's go Warrior! ";
        }
        else
        {
            cout << "Go up to get out. ";
        }
        cout << "Welcome to the lobby. There are 3 exits: east, west and up. Type listen to check around..." << endl;
        cout << "Enter your command:" << endl;
        cout << "------------------------------------------------" << endl;
        string str;
        getline(cin, str);
        return str;
    }

    void victory()
    {
        if (win)
        {
            cout << "------------------------------------------------" << endl;
            cout << "Victory! Congratulation!" << endl;
        }
        else
        {
            cout << "------------------------------------------------" << endl;
            cout << "You quit! Mission failed!" << endl;
        }
    }

    int type()
    {
        return 1;
    }
};

class cell
{
private:
    string name = "The cell.", str;

public:
    string enter()
    {
        cout << name << endl;
        cout << "The warrior has finally found the princess, who was imprisoned in a small cell. The cell was dimly lit with only a small torch on one wall. The walls were made of rough stone and there was a heavy iron door with a small barred window.\n"
                "The princess was sitting on a straw mat in the corner, looking pale and weak. She was wearing a torn and dirty dress, and her hair was matted and unkempt.\n"
                "The warrior approached the cell and tried to open the door, but it was locked from the outside. "
             << endl;
        if (key == true)
        {
            win = true;
            cout << "With the key, you quickly unlocked the door and the princess ran into his arms." << endl;
            cout << "Now you must take the princess away as fast as possible. Enter your command:" << endl;
        }
        else
        {
            win = false;
            cout << "You looked around for the key, but you couldn't find it. You tried to force the door open, but it was too strong.\n"
                    "Seeing the warrior's struggle, the princess got up and walked towards him. She whispered something in his ear\n"
                    "Now you need to find the key! Be careful!\n"
                    "Enter your command:"
                 << endl;
        }

        cout << "------------------------------------------------" << endl;
        getline(cin, str);
        return str;
    }

    int type()
    {
        return 2;
    }
};

class monster
{
private:
    string str = "Game Over...";

public:
    void enter()
    {

        cout << "There is an evil dragon lurked in the shadows. You are spotted by the dragon. It reared up on its hind legs and lashed out at you with its razor-sharp claws." << endl;
        cout << "The dragon struck a fatal blow, you fell to the ground, dead..." << endl;
        cout << "------------------------------------------------" << endl;
        cout << str << endl;
    }
    int type()
    {
        return 3;
    }
};

class empty_room
{
private:
    string str = "There is nothing here. Enter your command:";

public:
    string enter()
    {

        cout << str << endl;
        cout << "Enter your command:" << endl;
        cout << "------------------------------------------------" << endl;
        string exit;
        getline(cin, exit);
        return exit;
    }
    int type()
    {
        return -1;
    }
};

class wall
{
public:
    string enter()
    {
        string str;
        cout << "There is no way out forward! Try another way out:" << endl;
        cout << "------------------------------------------------" << endl;
        getline(cin, str);
        return str;
    }
};

class key_room
{
public:
    string enter()
    {
        string str;
        key = true;
        cout << "You find the loose stone that princess described. You pulled the stone out and found a small key hidden behind it.\n"
                "Now you have the key to the cell. Go to save the princess!\n"
                "Enter your command:"
             << endl;
        cout << "------------------------------------------------" << endl;
        getline(cin, str);
        return str;
    }
};

string enter_room(int num)
{
    string str;
    if (num == -1)
    {
        empty_room tmp;
        str = tmp.enter();
    }
    if (num == 1)
    {
        lobby tmp;
        str = tmp.enter();
    }

    if (num == 2)
    {
        cell tmp;
        str = tmp.enter();
    }

    if (num == 4)
    {
        key_room tmp;
        str = tmp.enter();
    }

    return str;
}

void search(int _i, int _j, Matrix _m)
{
    for (int i = _i - 1; i <= _i + 1; i++)
    {
        for (int j = _j - 1; j <= _j + 1; j++)
        {
            if (_m(i, j) == 3)
            {
                cout << "Dong...Dong...Dong...Some heavy sound of footsteps with raspy growl...Be careful!" << endl;
            }
        }
    }
}

int main()
{
    int n;
    cin >> n;
    getchar();
    Matrix m(n, n);
    srand(time(NULL));
    int r1 = rand() % (n - 3) + 2, r2 = rand() % (n - 4) + 2;
    m.set(r1, r2, 1);
    int r3 = rand() % (n - 2) + 1, r4 = rand() % (n - 2) + 1;
    for (int i = 2; i <= 4; i++)
    {
        while (1)
        {
            if (m(r3, r4) == -1)
            {
                m.set(r3, r4, i);
                break;
            }
            else
            {
                r3 = rand() % n;
                r4 = rand() % n;
            }
        }
    }

    int i = r1, j = r2;
    // cout << i << " " << j << endl;
    lobby tmp;
    //m.print(i, j);
    string str = tmp.enter();
    do
    {

        if (str == "go east")
        {
            j++;
        }
        if (str == "go west")
        {
            j--;
        }
        if (str == "go up")
        {
            i--;
        }
        if (str == "go down")
        {
            i++;
        }

        if (m(i, j) == 3)
        {
            monster dragon;
            // cout << i << " " << j << endl;
            dragon.enter();
            return 0;
        }
        else if (m(i, j) == 0)
        {
            wall w;
            if (str == "go east")
            {
                j--;
            }
            if (str == "go west")
            {
                j++;
            }
            if (str == "go up")
            {
                i++;
            }
            if (str == "go down")
            {
                i--;
            }
            // cout << i << " " << j << endl;
            m.print(i, j);
            str = w.enter();
        }
        else
        {
            cout << "You are here: " << endl;

            m.print(i, j);
            search(i, j, m);
            str = enter_room(m(i, j));
        }

    } while ((i != r1 || j != r2) || (win == false));
    tmp.victory();
    return 0;
}
